var util = require("../util");

module.exports = function(e, t) {
    var n = [], r = null, o = t && t.location && t.location.href, a = 0, i = undefined, s = null, u = function(e, t, n) {
        if (null !== e) {
            var r = e[t];
            e[t] = n(r);
        }
    }, c = function(e) {
        var t, n, r, o, a, i = [];
        if (!e || "string" != typeof e.tagName) return "";
        if (i.push(e.tagName.toLowerCase()), "string" == typeof e.id && i.push("#".concat(e.id)), 
        "string" == typeof (t = e.className)) for (n = t.split(/\s+/), a = 0; a < n.length; a++) i.push(".".concat(n[a]));
        var s = [ "type", "name", "title", "alt" ];
        for (a = 0; a < s.length; a++) r = s[a], "string" == typeof (o = e.getAttribute(r)) && i.push("[".concat(r, '="').concat(o, '"]'));
        return i.join("");
    }, f = function(e, t) {
        return function(n) {
            if (n && n !== s) {
                s = n;
                var o;
                try {
                    o = n.target;
                } catch (f) {
                    o = "<unknown>";
                }
                if (0 !== o.length) {
                    var u = {
                        type: "ui.".concat(e),
                        data: {
                            message: function(e) {
                                if (!e || 1 !== e.nodeType) return "";
                                for (var t = e || null, n = [], r = 0, o = 0, a = " > ".length, i = ""; t && r++ < 5 && !("html" === (i = c(t)) || r > 1 && o + n.length * a + i.length >= 80); ) n.push(i), 
                                o += i.length, t = t.parentNode;
                                return n.reverse().join(" > ");
                            }(o)
                        },
                        timestamp: Date.now()
                    };
                    "click" === e ? (a && clearTimeout(a), t ? a = setTimeout(function() {
                        r && r.addBehavior(u);
                    }, 0) : r && r.addBehavior(u)) : "keypress" === e && (i || r && r.addBehavior(u), 
                    clearTimeout(i), i = setTimeout(function() {
                        i = undefined;
                    }, 100));
                }
            }
        };
    }, h = function() {
        if (function() {
            var e = t && t.chrome, n = e && e.app && e.app.runtime, r = "history" in t && !!t.history.pushState && !!t.history.replaceState;
            return !n && r;
        }()) {
            var e = function(e, t) {
                var n = {
                    type: "navigation",
                    data: {
                        from: e,
                        to: t
                    }
                };
                r && r.addBehavior(n), o = t;
            }, n = t.onpopstate;
            t.onpopstate = function() {
                for (var r = arguments.length, a = new Array(r), i = 0; i < r; i++) a[i] = arguments[i];
                var s = t.location.href;
                if (e(o, s), n) return n.apply(this, a);
            };
            var a = function(t) {
                return function() {
                    for (var n = arguments.length, r = new Array(n), a = 0; a < n; a++) r[a] = arguments[a];
                    var i = r.length > 2 ? r[2] : undefined;
                    return i && e(o, String(i)), t.apply(this, r);
                };
            };
            u(t.history, "pushState", a), u(t.history, "replaceState", a);
        }
    };
    util.ext(e.prototype, {
        addBehavior: function(e) {
            if (this.getConfig("behavior") && e && "object" == typeof e) {
                var r = {}, o = e.data || {};
                if (e.type) r = o; else {
                    if ("string" != typeof o.name || "string" != typeof o.message) return;
                    r.name = o.name.substr(0, 20), r.message = o.message.substr(0, 200);
                }
                r.message && (r.message = util.encode(r.message));
                var a = {
                    type: e.type || "custom",
                    data: r || {},
                    timestamp: e.timestamp || Date.now(),
                    page: e.page || t && t.location && t.location.pathname
                };
                return n.push(a), n = n.slice(-100);
            }
        },
        getBehavior: function() {
            return n || [];
        },
        setBehavior: function(e) {
            return e && (n = e), n;
        },
        reportBehavior: function(e) {
            var t = this;
            t.getConfig("behavior") && (t.sendBhTimer && (clearTimeout(t.sendBhTimer), t.sendBhTimer = undefined), 
            t.sendBhTimer = setTimeout(function() {
                n && n.length > 0 && (t.behavior(n), n = [], t.sendBhTimer = undefined, e && "function" == typeof e && e());
            }, 0));
        },
        initBehavior: function() {
            if (!this.hasInitBehavior && !r) {
                try {
                    !function() {
                        if (document && document.referrer && document.location) {
                            var e = document.referrer, t = document.location.href;
                            if ("" !== e) {
                                var n = {
                                    type: "navigation",
                                    data: {
                                        from: e,
                                        to: t
                                    }
                                };
                                o = t, r && r.addBehavior(n);
                            }
                        }
                    }(), t && t.document && t.document.addEventListener && (t.document.addEventListener("click", f("click"), !1), 
                    t.document.addEventListener("keypress", f("keypress"), !1)), h(), this.getConfig("enableConsole") && function() {
                        if (t && t.console) for (var e = [ "debug", "info", "warn", "log", "error", "assert" ], n = 0; n < e.length; n++) {
                            var o = e[n];
                            t.console[o] && "function" == typeof t.console[o] && u(t.console, o, function(e) {
                                var n = o;
                                return function() {
                                    for (var o = arguments.length, a = new Array(o), i = 0; i < o; i++) a[i] = arguments[i];
                                    var s = {
                                        type: "console",
                                        data: {
                                            level: n,
                                            message: a
                                        }
                                    };
                                    if (r && r.addBehavior(s), "error" === n) for (var u = 0; u < a.length; u++) {
                                        var c = a[u];
                                        c && c.message && c.stack && r && r.errorHandler(new ErrorEvent("error", {
                                            error: c,
                                            message: c.message
                                        }));
                                    }
                                    e && Function.prototype.apply.call(e, t.console, a);
                                };
                            });
                        }
                    }();
                } catch (e) {
                    util.warn("[arms] error in initBehavior", e);
                }
                r = this, this.hasInitBehavior = !0;
            }
            return this;
        }
    });
};